.TITLE MLOCK .IDENT /04.03/ ; ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; All rights reserved ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; ; RICHARD H. ECKHOUSE, JR. 5-MAR-75 ; ; MODIFIED BY: ; ; J. M. LAWLER 07-JUL-83 04.01 ; ; JL167 -- MAKE PATCH SPACE UNCONDITIONAL ; ; J. W. BERZLE 08-SEP-83 04.02 ; ; JWB047 -- ADD BUGCHECK FACILITY AND ERROR CODES ; ; Modified for RSX-11M-PLUS V4.6 by: ; ; D. Carroll 18-Oct-1995 04.03 ; DC404 -- Include PSECT definition to allow ICB pool to be ; fully extended during sysgen ; ; ; MULTIPROCESSOR LOCKING SUBROUTINES ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,BGCK$A ;DC404 HWDDF$ ;DEFINE HARDWARE REGISTERS ;DC404 ;DC404 .IIF DF,K$$DAS&I$$CBP, .PSECT EXEC1 ;DC404 ;**-1 .IF DF M$$PRO ;**-2 ; ; LOCK WORDS ARE OF THE FORM: ; ; BYTE 0 = LOCK VALUE (0 IF LOCKED, 1 IF FREE) ; BYTE 1 = IF BYTE 0 EQUAL: ; 0, THEN BYTE 1 = OWNER OF LOCK ; 1, THEN BYTE 1 = COMPLEMENT OF ; PREVIOUS OWNER ; BYTE 2,3 = SECONDARY LOCK WORD (FORMAT ABOVE) FOR WAIT MASK. ; BYTE 4,5 = MASK OF WAITING PROCESSORS. ; ; NOTE: BYTES 4+5 ARE REFERENCED AS A WORD. ; ;+ ; **-$MLOCK-MULTIPROCESSOR WAIT-LOCK LOCK ROUTINE. ; ; THIS ROUTINE WILL USE THE ASRB INSTRUCTION TO LOCK A DATA STRUCTURE ; OR CODE SEGMENT. IT OPERATES ON LOCK BLOCKS DESCRIBED ABOVE. ; IT IS CALLED FROM AN INVOCATION OF THE LOCK$ MACRO WHEN THE LOCK TYPE ; IS "WAIT". IT WILL ATTEMPT THE LOCK, AND IF IT FAILS WILL POST THE ; FACT THAT THIS PROCESSOR IS WAITING, THEN PLACE ITSELF IN A WAIT STATE. ; THIS ROUTINE SHOULD ONLY BE CALLED AT PRIORITY ZERO, UNBYPASSED. ; WHEN IT EXITS, THE PRIORITY IS AGAIN ZERO, AND THE CACHE IS UNBYPASSED. ; ; INPUTS: ; ; 0(SP)=RETURN ADDRESS TO CALLER. ; 2(SP)=ADDRESS OF LOCK BLOCK. ; ; OUTPUTS: ; ; LOCK BLOCK IS LOCKED, AND THIS PROCESSOR IS OWNER. PRIORITY ; EQUALS ZERO, CACHE UNBYPASSED. CACHE HAS BEEN FLUSHED IF ; MORE THAN ONE PROCESSOR IS ACTIVE. ; ; ALL REGISTERS ARE PRESERVED. ;- $MLOCK::MOV R4,-(SP) ;SAVE R4 FOR LATER MFPS -(SP) ;SAVE PRIORITY MTPS #PR7 ;DON'T WANT TO BE INTERRUPTED HERE .IF DF P$$D70 MOV $URMST,R4 ;;;GET ONLINE BUS RUNS BIC $CPMSK,R4 ;;;MAKE IT CPUS ONLY BIC $CPBIT,R4 ;;;IGNORE OURSELVES BEQ 5$ ;;;IF EQ DON'T BOTHER TO FLUSH OR BYPASS BIS #BYPASS,@$MPCSR+6 ;;;FLUSH AND BYPASS THE CACHE 5$: ;;;REFERENCE LABEL .ENDC ; ; CURRENT STACK CONTENTS: ; ; 0(SP) = SAVED PRIORITY. ; 2(SP) = SAVED R4 FROM ENTRY. ; 4(SP) = RETURN ADDRESS TO CALLER. ; 6(SP) = ADDRESS OF LOCK BLOCK. ; MOV 6(SP),R4 ;;;GET LOCK ADDRESS .IF DF L$$DBG CMPB 1(R4),$PROCN ;;;DO WE OWN LOCK BEQ ERR5 ;;;IF EQ YES -- CRASH, NO WALK THRU .ENDC 10$: ASRB (R4) ;;;ATTEMPT THE LOCK BCS 20$ ;;;IF CS WE NOW OWN IT ; ; WE HAVE ATTEMPTED TO LOCK THE LOCK BYTE, AND FAILED TO GAIN ACCESS. ; WE WILL NOW POST THE FACT THAT WE ARE WAITING. ; LOCK$ 2(R4),SPIN ;;;LOCK THE SECONDARY LOCK BIS $CPBIT,4(R4) ;;;POST THE FACT THAT WE ARE WAITING ULOCK$ 2(R4),SPIN ;;;UNLOCK THE SECONDARY LOCK ASRB (R4) ;;;ATTEMPT THE PRIMARY LOCK AGAIN BCS 30$ ;;;IF CS WE GOT IT THIS TIME MTPS (SP) ;;;LOWER PRIORITY TO ENTRANCE VALUE TST $PWRFL ;;;SEE IF POWERFAIL FLAG IS SET BNE 15$ ;;;IF SET, SKIP WAIT INSTRUCTION BIT @$CPURM,$URMST ;;;ARE WE ONLINE YET? BEQ 15$ ;;;IF EQ NO -- NO IIST YET WAIT ;;;WAIT FOR ANY INTERRUPT 15$: MTPS #PR7 ;;;WE DON'T WANT TO BE INTERRUPTED BR 10$ ;;;TRY PRIMARY LOCK AGAIN ; ; WE HAVE GAINED ACCESS TO THE LOCK ; 20$: ;;;REFERENCE LABEL .IF DF L$$DBG 30$: CACHE$ BYPASS ;;;NEED TO CHECK OUT SOME REAL VALUES TSTB 1(R4) ;;;DOES LOCK ALREADY SHOW OWNED? BPL ERR4 ;;;IF PL YES -- SOMEHOW WE BROKE LOCK MOVB $PROCN,1(R4) ;;;SHOW US AS OWNER .IFTF CACHE$ RESTOR ;;;THRU WITH CHANGABLE VALUES .IFF 30$: ;;;REFERENCE LABEL .ENDC MTPS (SP)+ ;;;RESTORE PRIORITY MOV (SP)+,R4 ;RESTORE R4 MOV (SP)+,(SP) ;MOVE RETURN ADDRESS CACHE$ FLUSH ;FLUSH CACHE RETURN ERR4: BGCK$A BF.MP,BE.OCP,FATAL ;OTHER CPU SHOWED OWNERSHIP ERR5: BGCK$A BF.MP,BE.WTL,FATAL ;ATTEMPT TO WALK THRU LOCK ;+ ; **-$MULCK-MULTIPROCESSOR WAIT LOCK UNLOCK SUBROUTINE. ; ; THIS ROUTINE WILL UNLOCK THE SOFTWARE MULTIPROCESSOR LOCK, USING ; THE ASRB INSTRUCTION TO INTERLOCK MEMORY. IT WILL CHECK TO SEE ; IF ANY PROCESSOR IS WAITING, AND IF ANY ARE, IT WILL INTERRUPT THEM. ; ; INPUTS: ; ; 0(SP)=RETURN ADDRESS OF CALLER. ; 2(SP)=ADDRESS OF LOCK BLOCK. ; ; OUTPUTS: ; ; LOCK IS UNLOCKED. ANY WAITING PROCESSORS HAVE BEEN ; INTERRUPTED. ; ; PRIORITY IS PRESERVED AT EXIT, BUT MAY GO TO ZERO DURING ; THIS ROUTINES EXECUTION. ; ; CACHE IS UNBYPASSED. ; ; ALL REGISTERS ARE PRESERVED. ;- $MULCK::MOV R5,-(SP) ;SAVE R5 MOV R4,-(SP) ;SAVE R4 MOV 6(SP),R4 ;GET ADDRESS OF LOCK MFPS -(SP) ;SAVE PRIORITY FOR EXIT MTPS #PR7 ;RAISE PRIORITY SINCE WE WILL LOCK LATER .IF DF L$$DBG CMPB 1(R4),$PROCN ;DO WE OWN IT? BNE ERR1 ;IF NE NO -- CRASH ASRB (R4) ;IS LOCK LOCKED? BCS ERR3 ;NO - WE JUST GOT IT, OOPS COMB 1(R4) ;CLEAR WHO DONE IT .ENDC ; ; SEE IF ANY PROCESSOR IS WAITING ; LOCK$ 2(R4),SPIN ;;;LOCK SECONDARY LOCK IN LOCK BLOCK MOV 4(R4),R5 ;;;GET MASK OF WAITING PROCESSORS CLR 4(R4) ;;;CLEAR MASK OF WAITING PROCESSORS ; ; AT THIS POINT, WE WILL SET THE BITS IN $IICPU FOR THOSE CPUS WHICH ; ARE CURRENTLY WAITING, AND HAVE WORK TO DO ($IIPND). ; UNFORTUNATELY, WE MUST LOCK THE FORK LOCK TO DO THIS. ; ;******************************* IIST DEBUGGING CODE ***************** BR 4$ ;ENTER NEW CODE BR 6$ ;DON'T ENTER NEW CODE ;******************************* END IIST DEBUGGING CODE ************* 4$: MOV R5,-(SP) ;GET SOME SPACE TO WORK IN MOV $IIPND,-(SP) ;CALC $IIPND .AND. R5 COM (SP) ;CREATE MASK OF CPUS NOT HAVING WORK BIC (SP)+,R5 ;R5=CPUS WHICH HAVE WORK AND WILL BE INTED BEQ 5$ ;IF EQ DON'T BOTHER $IICPU LOCK$ $FORKL,SPIN ;LOCK ONCE MORE (YEECH) BIS R5,$IICPU ;SHOW OURS INTERRUPTED ULOCK$ $FORKL,SPIN ;UNLOCK FORK LIST LOCK 5$: MOV (SP)+,R5 ;RESTORE ORIGINAL R5 6$: MOVB #1,(R4) ;;;UNLOCK PRIMARY LOCK ULOCK$ 2(R4),SPIN ;;;UNLOCK SECONDARY LOCK BIC $CPBIT,R5 ;;;WE ALREADY HAD LOCK, SO CLEAR OUR BIT BEQ 10$ ;;;IF EQ NO CPU WAITING ; ; WE HAVE A MASK OF WAITING PROCESSORS ; MOV R0,-(SP) ;SAVE R0 MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) MOV R5,R1 ;SET UP PARAMETERS FOR $IIXMT CALL $IIXMT MOV (SP)+,R3 ;RESTORE R3 MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 10$: MTPS (SP)+ ;RESTORE PRIORITY TO SAME AS INCOMING MOV (SP)+,R4 ;RESTORE R4 MOV (SP)+,R5 MOV (SP)+,(SP) ;SLIDE RETURN ADDRESS DOWN STACK RETURN ERR1: BGCK$A BF.MP,BE.UNO,FATAL ;PROCESSOR WHO DIDN'T OWN LOCK ;TRIED TO UNLOCK ERR2: BGCK$A BF.MP,BE.ILC,FATAL ;ILLEGAL LOCK COUNT VALUE ERR3: BGCK$A BF.MP,BE.LNS,FATAL ;LOCK NOT SET ERR6: BGCK$A BF.MP,BE.MLK,FATAL ;ATTEMPT MADE TO EXIT MULTIPLE LOCK .IFTF ; DF M$$PRO $PATCH::.BLKW 40. ;PATCHING SPACE .ENDC .END